#include <iostream>
#include <iostream>
#include <fstream>
#include <sstream>
#include <cmath>
#include <vector>
#include <string>
#include <cstdlib>
#pragma once

using namespace std;

template <class T>
class interval
{
private:
	T lower;
	T upper;
public:

	interval(){ lower = upper = 0; }
	interval(T mean, double procent)
	{
		lower = mean - mean*procent/100.0;
		upper = mean + mean*procent/100.0;
	}

	~interval(void)
	{
	}

	T mean(){ return (lower + upper)/2; }
	double relative_error(){ return (upper-lower)/mean(); }
	double absolute_error(){ return (upper-lower); }

	friend interval<T> operator +(interval <T> &lop, interval <T> &hop)
	{
		interval <T> m;
		m.upper = lop.upper + hop.upper;
		m.lower = lop.lower + hop.lower;

		return m;
	}

	friend interval<T> operator -(interval <T> &lop, interval <T> &hop)
	{
		interval <T> m;
		m.upper = lop.upper - hop.upper;
		m.lower = lop.lower - hop.lower;

		return m;
	}

	friend interval <T> operator *(interval <T> &lop, interval <T> &hop)
	{
		interval <T> m;
		m.upper = max(max(lop.upper * hop.upper, lop.lower * hop.upper), max(lop.upper * hop.lower, lop.lower * hop.lower));
		m.lower = min(min(lop.upper * hop.upper, lop.lower * hop.upper), min(lop.upper * hop.lower, lop.lower * hop.lower));

		return m;
	}

	friend interval <T> operator /(interval <T> &lop, interval <T> &hop)
	{
		interval <T> m;
		if(!(lop.lower == 0 || lop.upper == 0 || hop.lower == 0 || hop.upper == 0))
		{
			m.upper = max(max(lop.upper / hop.upper, lop.lower / hop.upper), max(lop.upper / hop.lower, lop.lower / hop.lower));
			m.lower = min(min(lop.upper / hop.upper, lop.lower / hop.upper), min(lop.upper / hop.lower, lop.lower / hop.lower));
		}
		return m;
	}

	friend ostream& operator << (ostream& out, interval <T> m)
	{
		out << "[" << m.lower << ", " << m.upper << "]" <<endl;
		return out;
	}

};

